package net.cyndeline.entitySystem

import net.cyndeline.entitySystem.common.NullEntityRef

/**
 * Provides functionality for entity ID's.
 */
trait EntityRef {
  
  /**
   * @return The status of this entitys existence, if it has been
   * 		 deleted or not.
   */
  def exists: Boolean
  
  /**
   * @param component A component class.
   * @return If this entity has a component of the specified class.
   */
  def hasComponent(componentClass: Class[_ <: Component]): Boolean
  
  /**
   * @param A component class.
   * @return A component of the given class, if this entity owns one, otherwise
   * 		 None.
   */
  def getComponent[T <: Component](componentClass: Class[T]): Option[T]
  
  /**
   * Adds a component to this entity, or replaces a component of the same
   * type if one exists.
   * @return The component that this entity now contains.
   */
  def addComponent[T <: Component](component: T): Option[T]
  
  /**
   * Removes a component from this entity.
   * @param componentClass The component type to remove.
   */
  def removeComponent(componentClass: Class[_ <: Component]): Unit
  
  /**
   * @return An iterator containing all components of this entity.
   */
  def iterateComponents: Iterator[Component]
  
  /**
   * Removes all components from this entity.
   */
  def destroy(): Unit
  
  /**
   * Transmits an event to this entity.
   */
  def send(event: Event): Unit
  
  /**
   * Try not to use this unless necessary, prefer use of the EntityRef
   * whenever possible. 
   * @param The id of this entity.
   */
  def id: Int
  
  /**
   * The entity must have its id set, or it will be null by default.
   * @param setId The id of this entity.
   */
  def id_=(setId: Int)
  
  /**
   * Specifies which entity manager this entity should use.
   * @param A globally unique entity manager.
   */
  def entityManager_=(manager: EntityManager)
  
  /**
   * @return The entity manager used by this entity.
   */
  def entityManager: EntityManager

  def invalidate(): Unit // Sets a null-id
  
  /**
   * @return A deep copy of this entity.
   */
  def copy: EntityRef
}

object EntityRef {
  val NULL = new NullEntityRef
}